home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / test / testbtdel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  14.2 KB  |  612 lines

  1. /* ----------------------------------------------------------------
  2.  * testbtdel.c --
  3.  *    B-tree test code.
  4.  * ----------------------------------------------------------------
  5.  */
  6.  
  7. #include "fmgr.h"    /* for M_STATIC/M_DYNAMIC */
  8.  
  9. #include <stdio.h>
  10.  
  11. #include "c.h"
  12.  
  13. #include "attnum.h"
  14. #include "attval.h"
  15. #include "bufmgr.h"
  16. #include "catname.h"
  17. #include "datum.h"
  18. #include "log.h"
  19. #include "genam.h"
  20. #include "heapam.h"
  21. #include "itemptr.h"
  22. #include "istrat.h"
  23. #include "itup.h"
  24. #include "name.h"
  25. #include "oid.h"
  26. #include "portal.h"
  27. #include "sdir.h"
  28. #include "tqual.h"
  29. #include "valid.h"
  30. #include "xcxt.h"
  31.  
  32. #include "btree.h"
  33.  
  34. RcsId("$Header: /private/postgres/src/test/RCS/testbtdel.c,v 1.10 1992/03/04 14:10:35 hong Exp $");
  35.  
  36. /* ----------------
  37.  *    constants
  38.  * ----------------
  39.  */
  40.  
  41. #define UninitializedQualification    0
  42. #define SingleQualification        1
  43. #define DoubleQualification        2
  44. #define MarkedQualification        3
  45.  
  46. #define MarkedTuplesToProcess        64
  47.  
  48. static int        QualificationState;
  49. ScanKeyEntryData    QualificationKeyData[2];
  50.  
  51. AttributeNumber        indexAttrNumber;
  52. ObjectId         indexAttrClass;
  53.  
  54. /* ----------------------------------------------------------------
  55.  *               misc functions
  56.  * ----------------------------------------------------------------
  57.  */
  58.  
  59. /* ----------------
  60.  *    DoCreateIndex
  61.  * ----------------
  62.  */
  63.  
  64. void 
  65.    DoCreateIndex(heapName, indexName, attribute, cls)
  66. Name        heapName;
  67. Name        indexName;
  68. AttributeNumber attribute;
  69. ObjectId    cls;
  70. {
  71.    AttributeNumber  attributeNumber[1];
  72.    ObjectId        attributeClass[1];
  73.    
  74.    elog(NOTICE, "DoCreateIndex... start");
  75.    
  76.    attributeNumber[0] = attribute;
  77.    attributeClass[0] =  cls;
  78.    
  79.    /*
  80.    startmmgr(M_STATIC);        /* M_DYNAMIC is buggy */
  81.    
  82.    RelationNameCreateIndexRelation(heapName,
  83.                    indexName,
  84.                    400 /* B-tree AM */,
  85.                    1,
  86.                    attributeNumber,
  87.                    attributeClass,
  88.                    0,
  89.                    (Datum *) NULL);
  90.    /*
  91.    endmmgr(NULL);
  92.    */
  93.    
  94.    elog(NOTICE, "DoCreateIndex... end");
  95.    
  96. }
  97.  
  98. /* ----------------
  99.  *    ShowResult
  100.  * ----------------
  101.  */
  102.  
  103. void 
  104.    ShowResult(result, heapRelation)
  105. GeneralRetrieveIndexResult    result;
  106. Relation            heapRelation;
  107. {
  108.    ItemPointer    pointer;
  109.    
  110.    Assert(GeneralRetrieveIndexResultIsValid(result));
  111.    
  112.    pointer = GeneralRetrieveIndexResultGetHeapItemPointer(result);
  113.    
  114.    printf("\t");
  115.    
  116.    if (!ItemPointerIsValid(pointer)) {
  117.       printf("<invalid>\n");
  118.    } else {
  119.       HeapTuple    tuple;
  120.       Buffer    buffer;
  121.       
  122.       printf("[b,p,o %d, %d, %3d] ",
  123.          ItemPointerGetBlockNumber(pointer),
  124.          ItemPointerSimpleGetPageNumber(pointer),
  125.          ItemPointerSimpleGetOffsetNumber(pointer));
  126.       
  127.       tuple =
  128.      RelationGetHeapTupleByItemPointer(heapRelation,
  129.             NowTimeQual,
  130.                        pointer,
  131.                        &buffer);
  132.       
  133.       if (!HeapTupleIsValid(tuple)) {
  134.      printf("*NULL*\n");
  135.      
  136.       } else {
  137.      TupleDescriptor    descriptor;
  138.      AttributeValue        value;
  139.      Boolean        valueIsNull;
  140.      
  141.      descriptor = RelationGetTupleDescriptor(heapRelation);
  142.      
  143.      /* may want to print more than just the index attribute, here */
  144.      value =
  145.         HeapTupleGetAttributeValue(tuple,
  146.                        buffer,
  147.                        indexAttrNumber,
  148.                        descriptor,
  149.                        &valueIsNull);
  150.      
  151.      if (valueIsNull) {
  152.         printf("<NULL>\n");
  153.      } else {
  154.         printf("<0x%x(%d)>\n",
  155.            DatumGetObjectId(value), 
  156.            DatumGetObjectId(value));
  157.      }
  158.      
  159.      ReleaseBuffer(buffer);
  160.       }
  161.    }
  162. }
  163.  
  164. /* ----------------
  165.  *    ShowScanKeyEntry
  166.  * ----------------
  167.  */
  168.  
  169. void 
  170.    ShowScanKeyEntry(entry)
  171. ScanKeyEntry    entry;
  172. {
  173.    printf("Qualification is procedure 0x%x(%d) for %d with 0x%x\n",
  174.       entry->procedure,
  175.       entry->procedure,
  176.       DatumGetObjectId(entry->argument),
  177.       entry->flags);
  178. }
  179.  
  180. /* ----------------------------------------------------------------
  181.  *            browse functions
  182.  * ----------------------------------------------------------------
  183.  */
  184.  
  185. /* ----------------
  186.  *    DoBTreeBrowse
  187.  * ----------------
  188.  */
  189.  
  190. /*ARGSUSED*/
  191. void 
  192.    DoBTreeBrowse(indexRelation, heapRelation)
  193. Relation    indexRelation;
  194. Relation    heapRelation;
  195. {
  196.    BTreeNode   node;
  197.    BlockNumber blockNumber;
  198.    PageNumber  pageNumber;
  199.    OffsetIndex off;
  200.    int cnt;
  201.    
  202.    puts("\n--- BTree Browse ---");
  203.    puts("at the prompt, enter a block number and a page number");
  204.    puts("separated by a space or \".\" alone to end\n");
  205.    
  206.    forever {
  207.     forever {
  208.        Puts("browse> ");
  209.        fflush(stdout);
  210.           
  211.        cnt = scanf("%d %d", &blockNumber, &pageNumber);
  212.        if (cnt != 2) {
  213.         puts("\n--- ending BTree Browse ---");
  214.         fseek(stdin, 0, 2);
  215.         break;
  216.        }
  217.          
  218.        node = RelationFormBTreeNode(indexRelation, blockNumber, pageNumber);
  219.        DumpBTreeNode(node);
  220.        BTreeNodeFree(node);
  221.        putchar('\n');
  222.     }
  223.  
  224.     Puts("Enter offset number: ");
  225.     cnt = scanf("%hd", &off);
  226.     if (cnt != 1) {
  227.         puts("\n--- no more deletion ---");
  228.         fseek(stdin, 0, 2);
  229.         break;
  230.     }
  231.  
  232.     /* do it */
  233.     BTreeIndexTupleDelete(node, off);
  234.    }
  235. }
  236.  
  237. /* ----------------------------------------------------------------
  238.  *              scan functions
  239.  * ----------------------------------------------------------------
  240.  */
  241.  
  242. /* ----------------
  243.  *    DoForwardScan
  244.  * ----------------
  245.  */
  246.  
  247. void 
  248.    DoForwardScan(indexRelation, heapRelation)
  249. Relation    indexRelation;
  250. Relation    heapRelation;
  251. {
  252.    IndexScan            scan;
  253.    GeneralRetrieveIndexResult    result;
  254.    
  255.    puts("A complete forward scan of the index reveals...");
  256.  
  257.    scan = RelationGetIndexScan(indexRelation, 0, 0, (ScanKey) NULL);
  258.    while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 0),
  259.       GeneralRetrieveIndexResultIsValid(result))
  260.       {
  261.      ShowResult(result, heapRelation);
  262.       }
  263.    IndexScanEnd(scan);
  264. }
  265.  
  266. /* ----------------
  267.  *    DoBackwardScan
  268.  * ----------------
  269.  */
  270.  
  271. void 
  272.    DoBackwardScan(indexRelation, heapRelation)
  273. Relation    indexRelation;
  274. Relation    heapRelation;
  275. {
  276.    IndexScan            scan;
  277.    GeneralRetrieveIndexResult    result;
  278.    
  279.    puts("A complete reverse scan of the index reveals...");
  280.  
  281.    scan = RelationGetIndexScan(indexRelation, -1, 0, (ScanKey) NULL);
  282.    while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 1),
  283.       GeneralRetrieveIndexResultIsValid(result))
  284.       {
  285.      ShowResult(result, heapRelation);
  286.       }
  287.    IndexScanEnd(scan);
  288. }
  289.  
  290.  
  291. /* ----------------
  292.  *    DoSingleQualification
  293.  * ----------------
  294.  */
  295.  
  296. void 
  297.    DoSingleQualification(indexRelation, heapRelation, entry)
  298. Relation    indexRelation;
  299. Relation    heapRelation;
  300. ScanKeyEntry    entry;
  301. {
  302.    IndexScan            scan;
  303.    GeneralRetrieveIndexResult    result;
  304.    
  305.    QualificationKeyData[0] = *entry;
  306.    
  307.    ShowScanKeyEntry(&QualificationKeyData[0]);
  308.    puts("A SingleQual scan of the index reveals...");
  309.    
  310.    scan = RelationGetIndexScan(indexRelation, 0, 1,
  311.                    (ScanKey)QualificationKeyData);
  312.    while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 0),
  313.       GeneralRetrieveIndexResultIsValid(result))
  314.       {
  315.      ShowResult(result, heapRelation);
  316.       }
  317.    IndexScanEnd(scan);
  318. }
  319.  
  320.  
  321. /* ----------------
  322.  *    DoDoubleQualification
  323.  * ----------------
  324.  */
  325.  
  326. void 
  327.    DoDoubleQualification(indexRelation, heapRelation, entry)
  328. Relation    indexRelation;
  329. Relation    heapRelation;
  330. ScanKeyEntry    entry;
  331. {
  332.    IndexScan            scan;
  333.    GeneralRetrieveIndexResult    result;
  334.    
  335.    QualificationKeyData[1] = *entry;
  336.    
  337.    ShowScanKeyEntry(&QualificationKeyData[0]);
  338.    ShowScanKeyEntry(&QualificationKeyData[1]);
  339.    puts("A DoubleQual scan of the index reveals...");
  340.    
  341.    scan = RelationGetIndexScan(indexRelation, 0, 2,
  342.                    (ScanKey)QualificationKeyData);
  343.    while (result = IndexScanGetGeneralRetrieveIndexResult(scan, 0),
  344.       GeneralRetrieveIndexResultIsValid(result))
  345.       {
  346.      ShowResult(result, heapRelation);
  347.       }
  348.    IndexScanEnd(scan);
  349. }
  350.  
  351. /* ----------------
  352.  *    DoMarkedQualification
  353.  * ----------------
  354.  */
  355.  
  356. void 
  357.    DoMarkedQualification(indexRelation, heapRelation, entry)
  358. Relation    indexRelation;
  359. Relation    heapRelation;
  360. ScanKeyEntry    entry;
  361. {
  362.    IndexScan            scan;
  363.    GeneralRetrieveIndexResult    result;
  364.    int                tuplesLeft;
  365.    bool                markIsSet;
  366.    
  367.    tuplesLeft = MarkedTuplesToProcess;
  368.    markIsSet = false;
  369.  
  370.    srandom((int)time(0));
  371.    
  372.    QualificationKeyData[0] = *entry;
  373.    
  374.    ShowScanKeyEntry(&QualificationKeyData[0]);
  375.    puts("A MarkedQual scan of the index reveals...");
  376.    
  377.    scan = RelationGetIndexScan(indexRelation, 0x1 & random(), 1,
  378.                    (ScanKey)QualificationKeyData);
  379.    
  380.    while (tuplesLeft > 0) {
  381.       if (!(random() & 0xf)) {
  382.      printf("RESTARTING SCAN\n");
  383.      IndexScanRestart(scan,
  384.               0x1 & random(),
  385.               &QualificationKeyData[0]);
  386.      markIsSet = false;
  387.       }
  388.       if (!(random() & 0x3)) {
  389.      if (markIsSet) {
  390.         printf("RESTORING MARK\n");
  391.         IndexScanRestorePosition(scan);
  392.         if (!(0x1 & random())) {
  393.            markIsSet = false;
  394.         }
  395.      } else {
  396.         printf("SET MARK\n");
  397.         IndexScanMarkPosition(scan);
  398.         markIsSet = true;
  399.      }
  400.       }
  401.       
  402.       result = IndexScanGetGeneralRetrieveIndexResult(scan, 0x1 & random());
  403.       if (!GeneralRetrieveIndexResultIsValid(result)) {
  404.      puts("\t*NULL*");
  405.       } else {
  406.      ShowResult(result, heapRelation);
  407.       }
  408.       
  409.       tuplesLeft -= 1;
  410.    }
  411.    IndexScanEnd(scan);
  412. }
  413.  
  414. /* ----------------------------------------------------------------
  415.  *    DoQualifiedScan
  416.  * ----------------------------------------------------------------
  417.  */
  418.  
  419. void 
  420.    DoQualifiedScan(indexRelation, heapRelation, operation, flags, returnType)
  421. Relation    indexRelation;
  422. Relation    heapRelation;
  423. char        *operation;
  424. uint16        flags;
  425. ObjectId    returnType;
  426. {
  427.    StrategyNumber    strategyNumber;
  428.    IndexStrategy    indexStrategy;
  429.    StrategyMap        strategyMap;
  430.    ScanKeyEntry        scanKeyEntry;
  431.    
  432.    if (strcmp(operation, "<") == 0) {    
  433.       strategyNumber = BTreeLessThanStrategyNumber;
  434.    } else if (strcmp(operation, "<=") == 0) {
  435.       strategyNumber = BTreeLessThanOrEqualStrategyNumber;
  436.    } else if (strcmp(operation, "=") == 0) {
  437.       strategyNumber = BTreeEqualStrategyNumber;
  438.    } else if (strcmp(operation, ">=") == 0) {
  439.       strategyNumber = BTreeGreaterThanOrEqualStrategyNumber;
  440.    } else if (strcmp(operation, ">") == 0) {
  441.       strategyNumber = BTreeGreaterThanStrategyNumber;
  442.    } else {
  443.       fprintf(stderr, "testbtdel: unknown operation \"%s\"\n",
  444.           operation);
  445.       return;
  446.    }
  447.    
  448.    indexStrategy = RelationGetIndexStrategy(indexRelation);
  449.    
  450.    strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
  451.                          BTreeNumberOfStrategies, 1);
  452.    
  453.    scanKeyEntry = StrategyMapGetScanKeyEntry(strategyMap, strategyNumber);
  454.    
  455.    if (!RegProcedureIsValid(scanKeyEntry->procedure)) {
  456.       fprintf(stderr, "testbtdel: no procedure for strategy %d\n",
  457.           strategyNumber);
  458.       
  459.       return;
  460.    }
  461.    
  462.    /*
  463.     * Note: very dangerous to modify the reldesc, since it is cached.
  464.     */
  465.    scanKeyEntry->attributeNumber = 1;
  466.    scanKeyEntry->flags = flags;
  467.    scanKeyEntry->argument = ObjectIdGetDatum(returnType);
  468.    
  469.    switch (QualificationState) {
  470.    case UninitializedQualification:
  471.    case MarkedQualification:
  472.       QualificationState = SingleQualification;
  473.       DoSingleQualification(indexRelation, heapRelation,
  474.                 scanKeyEntry);
  475.       break;
  476.    case SingleQualification:
  477.       QualificationState = DoubleQualification;
  478.       DoDoubleQualification(indexRelation, heapRelation,
  479.                 scanKeyEntry);
  480.       break;
  481.    case DoubleQualification:
  482.       QualificationState = MarkedQualification;
  483.       DoMarkedQualification(indexRelation, heapRelation,
  484.                 scanKeyEntry);
  485.       break;
  486.    default:
  487.       fprintf(stderr, "testbtdel: internal error!");
  488.       exitpg(255);
  489.    }
  490. }
  491.  
  492. /* ----------------------------------------------------------------
  493.  *                 TestMain
  494.  * ----------------------------------------------------------------
  495.  */
  496.  
  497. void 
  498. TestMain()
  499. {
  500.    static NameData    heapNameData;
  501.    static NameData     indexNameData;
  502.           Relation    indexRelation;
  503.           Relation    heapRelation;
  504.    static int            beenHere = 0;
  505.       Portal portal;
  506.    
  507.    
  508.    Relation        AMopenr();    /* XXX */
  509.  
  510.    
  511.    portal = CreatePortal("<blank>");
  512.    StartTransactionCommand(portal);
  513.  
  514.    if (beenHere == 0) {
  515.  
  516.       /* discard any stuff on the input stream */
  517.       fseek(stdin, 0, 2);
  518.  
  519.       puts("Please enter a heap relation name");
  520.       if (scanf("%s", heapNameData.data) != 1) {
  521.      elog(NOTICE, "testbtdel: no heap specified");
  522.      exitpg(0);
  523.       }
  524.       puts("Please enter an index name");
  525.       if (scanf("%s", indexNameData.data) != 1) {
  526.      elog(NOTICE, "testbtdel: no index specified");
  527.      exitpg(0);
  528.       }
  529.       
  530.       puts("Please enter an attribute number to index");
  531.       puts("If the relation is already indexed, enter");
  532.       puts("the negative of the index attribute number");
  533.       if (scanf("%hd", &indexAttrNumber) != 1) {
  534.      elog(NOTICE, "testbtdel: attribute incorrectly specified");
  535.      exitpg(0);
  536.       }
  537.       
  538.       if (indexAttrNumber > 0) {
  539.      puts("Please enter the operator class of the attribute");
  540.      puts("--> hint: intops = 421 <--");
  541.      if (scanf("%d", &indexAttrClass) != 1) {
  542.         elog(NOTICE, "testbtdel: op class incorrectly specified");
  543.         exitpg(0);
  544.      }
  545.      
  546.      fseek(stdin, 0, 2);
  547.      
  548.      beenHere = 1;
  549.      
  550.      DoCreateIndex(&heapNameData, &indexNameData,
  551.                indexAttrNumber, indexAttrClass);
  552.  
  553.       } else {
  554.          indexAttrNumber = -indexAttrNumber;
  555.       }
  556.  
  557.       CommitTransactionCommand();
  558.       StartTransactionCommand(portal);
  559.  
  560.       beenHere = 2;
  561.       
  562.    } else if (beenHere == 1) {
  563.       elog(NOTICE, "testbtdel: %s relation may exist--continuing!",
  564.        indexNameData.data);
  565.       beenHere = 2;
  566.       
  567.    } else if (beenHere > 1) {
  568.       elog(FATAL, "testbtdel: giving up!");
  569.    }
  570.  
  571.    QualificationState = UninitializedQualification;
  572.    
  573.    indexRelation = AMopenr(indexNameData.data);
  574.    heapRelation = RelationNameOpenHeapRelation(heapNameData.data);
  575.  
  576.    DoBTreeBrowse(indexRelation, heapRelation);
  577.  
  578.    DoForwardScan(indexRelation, heapRelation);
  579.    
  580.    DoBackwardScan(indexRelation, heapRelation);
  581.  
  582.    for (;;) {
  583.       int        status;
  584.       NameData        operatorNameData;
  585.       int        flags;
  586.       ObjectId        returnType;
  587.       
  588.       puts("\nPlease enter an operator, flags, and an integer value");
  589.  
  590.       fseek(stdin, 0, 2);    /* discard any stuff on the input stream */
  591.       status = scanf("%s%d%d", &(operatorNameData), &flags,
  592.              &returnType);
  593.       
  594.       if (status <= 0) {
  595.      break;
  596.       } else if (status != 3) {
  597.      elog(NOTICE, "testbtdel: improper qualification specified");
  598.      exitpg(0);
  599.       }
  600.       
  601.       DoQualifiedScan(indexRelation, heapRelation, &operatorNameData,
  602.               flags, returnType);
  603.    }
  604.    
  605.    RelationCloseHeapRelation(heapRelation);
  606.    RelationCloseIndexRelation(indexRelation);
  607.    
  608.    CommitTransactionCommand();
  609.  
  610.    puts("\nDone!");
  611. }
  612.